/*
 * executable_file.c
 *
 *  Created on: 03/10/2013
 *      Author: vitor
 */

#include "executable_file.h"

unsigned char readByte(FILE* fp) {
	unsigned char toReturn;

	toReturn = getc(fp);

	return toReturn;
}

unsigned int read4Bytes(FILE* fp) {
	unsigned int toReturn;

	toReturn = readByte(fp);
	toReturn = toReturn << 8 | readByte(fp);
	toReturn = toReturn << 8 | readByte(fp);
	toReturn = toReturn << 8 | readByte(fp);

	return toReturn;
}

unsigned short read2Bytes(FILE* fp) {
	unsigned short toReturn;

	toReturn = readByte(fp);
	toReturn = toReturn << 8 | readByte(fp);

	return toReturn;
}

executableFile parseProgram(char* fileName) {
	executableFile toReturn;
	unsigned int magic;
	int i = 0;
	FILE* fp;

	memset(&toReturn, 0, sizeof(executableFile));

	fp = fopen(fileName, "rb");

	if ((magic = read4Bytes(fp)) != 0xDEADCAFE) {
		fprintf(stderr, "Header errado, esperava 0xDEADCAFE, encontrou: %x.\n",
				magic);
		exit(1);
	}

	toReturn.executionStartAddress = read2Bytes(fp);
	toReturn.dataSegmentSize = read2Bytes(fp);

	// Lê o segmento de dados
	while (i < toReturn.dataSegmentSize) {
		toReturn.program[BASE_DATA + i] = readByte(fp);
		i++;
	}

	i = 0;

	// Lê o segmento de código
	while (!feof(fp)) {
		toReturn.program[BASE_CODE + i] = readByte(fp);
		i++;
	}

	fclose(fp);

	return toReturn;
}
